<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>智能快递柜管理系统</title>
    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
    <!-- Vue.js -->
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <!-- Axios -->
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <style>
        .main-container {
            margin-top: 20px;
        }
        .card {
            margin-bottom: 20px;
        }
        .status-available {
            color: #28a745;
        }
        .status-occupied {
            color: #dc3545;
        }
        .status-maintenance {
            color: #ffc107;
        }
        .compartment-grid {
            display: grid;
            grid-template-columns: repeat(5, 1fr);
            gap: 10px;
            margin-top: 20px;
        }
        .compartment-item {
            border: 2px solid #ddd;
            padding: 10px;
            text-align: center;
            border-radius: 5px;
        }
        .compartment-available {
            background-color: #d4edda;
            border-color: #28a745;
        }
        .compartment-occupied {
            background-color: #f8d7da;
            border-color: #dc3545;
        }
        .compartment-maintenance {
            background-color: #fff3cd;
            border-color: #ffc107;
        }
    </style>
</head>
<body>
    <div id="app">
        <!-- 导航栏 -->
        <nav class="navbar navbar-expand-lg navbar-dark bg-primary">
            <div class="container">
                <a class="navbar-brand" href="#">智能快递柜管理系统</a>
                <div class="navbar-nav me-auto">
                    <a class="nav-link" href="#" @click="currentView = 'home'" :class="{active: currentView === 'home'}">首页</a>
                    <a class="nav-link" href="#" @click="currentView = 'deposit'" :class="{active: currentView === 'deposit'}">存件</a>
                    <a class="nav-link" href="#" @click="currentView = 'pickup'" :class="{active: currentView === 'pickup'}">取件</a>
                    <a class="nav-link" href="#" @click="currentView = 'query'" :class="{active: currentView === 'query'}">查询</a>
                    <a class="nav-link" href="#" @click="currentView = 'management'" :class="{active: currentView === 'management'}">管理</a>
                </div>
                <div class="navbar-nav">
                    <span class="navbar-text me-3">
                        当前角色：<span class="badge bg-light text-dark">{{ user.roleName || '普通用户' }}</span>
                    </span>
                    <button v-if="!user.isAdmin" class="btn btn-outline-light btn-sm me-2" @click="showLoginModal = true">
                        管理员登录
                    </button>
                    <button v-if="user.isAdmin" class="btn btn-outline-light btn-sm" @click="logout">
                        登出
                    </button>
                </div>
            </div>
        </nav>

        <!-- 主内容区域 -->
        <div class="container main-container">
            <!-- 首页 -->
            <div v-if="currentView === 'home'">
                <h2>欢迎使用智能快递柜管理系统</h2>
                <div class="row">
                    <div class="col-md-3">
                        <div class="card bg-success text-white">
                            <div class="card-body">
                                <h5 class="card-title">可用柜格</h5>
                                <h3>{{ statistics.AVAILABLE || 0 }}</h3>
                            </div>
                        </div>
                    </div>
                    <div class="col-md-3">
                        <div class="card bg-danger text-white">
                            <div class="card-body">
                                <h5 class="card-title">占用柜格</h5>
                                <h3>{{ statistics.OCCUPIED || 0 }}</h3>
                            </div>
                        </div>
                    </div>
                    <div class="col-md-3">
                        <div class="card bg-warning text-white">
                            <div class="card-body">
                                <h5 class="card-title">维护柜格</h5>
                                <h3>{{ statistics.MAINTENANCE || 0 }}</h3>
                            </div>
                        </div>
                    </div>
                    <div class="col-md-3">
                        <div class="card bg-info text-white">
                            <div class="card-body">
                                <h5 class="card-title">总柜格数</h5>
                                <h3>{{ statistics.TOTAL || 0 }}</h3>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

            <!-- 存件页面 -->
            <div v-if="currentView === 'deposit'">
                <div class="row">
                    <div class="col-md-8 offset-md-2">
                        <div class="card">
                            <div class="card-header">
                                <h5>快递存件</h5>
                            </div>
                            <div class="card-body">
                                <form @submit.prevent="depositPackage">
                                    <div class="row">
                                        <div class="col-md-6">
                                            <div class="mb-3">
                                                <label class="form-label">快递单号</label>
                                                <input type="text" class="form-control" v-model="depositForm.trackingNumber" required>
                                            </div>
                                        </div>
                                        <div class="col-md-6">
                                            <div class="mb-3">
                                                <label class="form-label">快递公司</label>
                                                <select class="form-select" v-model="depositForm.expressCompanyId" required>
                                                    <option value="">请选择快递公司</option>
                                                    <option v-for="company in companies" :key="company.id" :value="company.id">
                                                        {{ company.companyName }}
                                                    </option>
                                                </select>
                                            </div>
                                        </div>
                                    </div>
                                    <div class="row">
                                        <div class="col-md-6">
                                            <div class="mb-3">
                                                <label class="form-label">寄件人姓名</label>
                                                <input type="text" class="form-control" v-model="depositForm.senderName" required>
                                            </div>
                                        </div>
                                        <div class="col-md-6">
                                            <div class="mb-3">
                                                <label class="form-label">寄件人电话</label>
                                                <input type="tel" class="form-control" v-model="depositForm.senderPhone" required>
                                            </div>
                                        </div>
                                    </div>
                                    <div class="row">
                                        <div class="col-md-6">
                                            <div class="mb-3">
                                                <label class="form-label">收件人姓名</label>
                                                <input type="text" class="form-control" v-model="depositForm.recipientName" required>
                                            </div>
                                        </div>
                                        <div class="col-md-6">
                                            <div class="mb-3">
                                                <label class="form-label">收件人电话</label>
                                                <input type="tel" class="form-control" v-model="depositForm.recipientPhone" required>
                                            </div>
                                        </div>
                                    </div>
                                    <div class="mb-3">
                                        <label class="form-label">收件人地址</label>
                                        <input type="text" class="form-control" v-model="depositForm.recipientAddress">
                                    </div>
                                    <div class="mb-3">
                                        <label class="form-label">包裹尺寸</label>
                                        <select class="form-select" v-model="depositForm.packageSize" required>
                                            <option value="">请选择包裹尺寸</option>
                                            <option value="SMALL">小件</option>
                                            <option value="MEDIUM">中件</option>
                                            <option value="LARGE">大件</option>
                                        </select>
                                    </div>
                                    <button type="submit" class="btn btn-primary" :disabled="loading">
                                        {{ loading ? '存件中...' : '存件' }}
                                    </button>
                                </form>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

            <!-- 取件页面 -->
            <div v-if="currentView === 'pickup'">
                <div class="row">
                    <div class="col-md-6 offset-md-3">
                        <div class="card">
                            <div class="card-header">
                                <h5>快递取件</h5>
                            </div>
                            <div class="card-body">
                                <form @submit.prevent="pickupPackage">
                                    <div class="mb-3">
                                        <label class="form-label">取件码</label>
                                        <input type="text" class="form-control" v-model="pickupForm.pickupCode" maxlength="6" required>
                                    </div>
                                    <div class="mb-3">
                                        <label class="form-label">收件人电话</label>
                                        <input type="tel" class="form-control" v-model="pickupForm.recipientPhone" required>
                                    </div>
                                    <button type="submit" class="btn btn-success" :disabled="loading">
                                        {{ loading ? '取件中...' : '取件' }}
                                    </button>
                                </form>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

            <!-- 查询页面 -->
            <div v-if="currentView === 'query'">
                <div class="row">
                    <div class="col-md-10 offset-md-1">
                        <div class="card">
                            <div class="card-header">
                                <h5>快递查询</h5>
                            </div>
                            <div class="card-body">
                                <div class="row">
                                    <div :class="user.isAdmin ? 'col-md-4' : 'col-md-6'">
                                        <div class="card">
                                            <div class="card-body">
                                                <h6>按取件码查询</h6>
                                                <form @submit.prevent="queryByPickupCode">
                                                    <div class="mb-3">
                                                        <input type="text" class="form-control" v-model="queryForm.pickupCode" placeholder="取件码" maxlength="6" required>
                                                    </div>
                                                    <div class="mb-3">
                                                        <input type="tel" class="form-control" v-model="queryForm.recipientPhone" placeholder="收件人电话" required>
                                                    </div>
                                                    <button type="submit" class="btn btn-primary" :disabled="loading">
                                                        {{ loading ? '查询中...' : '查询' }}
                                                    </button>
                                                </form>
                                            </div>
                                        </div>
                                    </div>
                                    <div :class="user.isAdmin ? 'col-md-4' : 'col-md-6'">
                                        <div class="card">
                                            <div class="card-body">
                                                <h6>按快递单号查询</h6>
                                                <form @submit.prevent="queryByTrackingNumber">
                                                    <div class="mb-3">
                                                        <input type="text" class="form-control" v-model="queryForm.trackingNumber" placeholder="快递单号" required>
                                                    </div>
                                                    <button type="submit" class="btn btn-primary" :disabled="loading">
                                                        {{ loading ? '查询中...' : '查询' }}
                                                    </button>
                                                </form>
                                            </div>
                                        </div>
                                    </div>
                                    <div v-if="user.isAdmin" class="col-md-4">
                                        <div class="card border-warning">
                                            <div class="card-body">
                                                <h6>仅按取件码查询 <span class="badge bg-warning text-dark">管理员</span></h6>
                                                <form @submit.prevent="queryByPickupCodeOnly">
                                                    <div class="mb-3">
                                                        <input type="text" class="form-control" v-model="queryForm.pickupCodeOnly" placeholder="取件码" maxlength="6" required>
                                                    </div>
                                                    <button type="submit" class="btn btn-warning" :disabled="loading">
                                                        {{ loading ? '查询中...' : '管理员查询' }}
                                                    </button>
                                                    <small class="form-text text-muted">无需电话验证</small>
                                                </form>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                                
                                <!-- 查询结果 -->
                                <div v-if="queryResult" class="mt-4">
                                    <div class="card">
                                        <div class="card-header">
                                            <h6>查询结果</h6>
                                        </div>
                                        <div class="card-body">
                                            <div class="row">
                                                <div class="col-md-6">
                                                    <p><strong>快递单号：</strong>{{ queryResult.trackingNumber }}</p>
                                                    <p><strong>取件码：</strong><span class="badge bg-primary">{{ queryResult.pickupCode }}</span></p>
                                                    <p><strong>寄件人：</strong>{{ queryResult.senderName }}</p>
                                                    <p><strong>寄件人电话：</strong>{{ queryResult.senderPhone }}</p>
                                                    <p><strong>收件人：</strong>{{ queryResult.recipientName }}</p>
                                                    <p><strong>收件人电话：</strong>{{ queryResult.recipientPhone }}</p>
                                                </div>
                                                <div class="col-md-6">
                                                    <p><strong>收件地址：</strong>{{ queryResult.recipientAddress || '未填写' }}</p>
                                                    <p><strong>包裹状态：</strong>
                                                        <span class="badge" :class="getStatusClass(queryResult.packageStatus)">
                                                            {{ getStatusText(queryResult.packageStatus) }}
                                                        </span>
                                                    </p>
                                                    <p><strong>存放时间：</strong>{{ formatDateTime(queryResult.depositTime) }}</p>
                                                    <p v-if="queryResult.pickupTime"><strong>取件时间：</strong>{{ formatDateTime(queryResult.pickupTime) }}</p>
                                                    <p v-if="queryResult.expireTime"><strong>过期时间：</strong>{{ formatDateTime(queryResult.expireTime) }}</p>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

            <!-- 管理页面 -->
            <div v-if="currentView === 'management'">
                <div class="row" v-if="user.isAdmin">
                    <!-- 密码管理卡片 -->
                    <div class="col-md-12 mb-4">
                        <div class="card">
                            <div class="card-header">
                                <h5><i class="fas fa-key"></i> 管理员账户管理</h5>
                            </div>
                            <div class="card-body">
                                <div class="row">
                                    <div class="col-md-6">
                                        <h6>修改密码</h6>
                                        <form @submit.prevent="changePassword">
                                            <div class="mb-3">
                                                <label class="form-label">当前用户名</label>
                                                <input type="text" class="form-control" v-model="passwordForm.username" 
                                                       placeholder="默认：admin" required>
                                            </div>
                                            <div class="mb-3">
                                                <label class="form-label">新密码</label>
                                                <input type="password" class="form-control" v-model="passwordForm.newPassword" 
                                                       placeholder="请输入新密码" minlength="6" required>
                                                <small class="form-text text-muted">密码长度至少6位</small>
                                            </div>
                                            <div class="mb-3">
                                                <label class="form-label">确认新密码</label>
                                                <input type="password" class="form-control" v-model="passwordForm.confirmPassword" 
                                                       placeholder="请再次输入新密码" required>
                                            </div>
                                            <button type="submit" class="btn btn-warning" :disabled="loading">
                                                <i class="fas fa-key"></i> {{ loading ? '修改中...' : '修改密码' }}
                                            </button>
                                        </form>
                                    </div>
                                    <div class="col-md-6">
                                        <h6>安全提醒</h6>
                                        <div class="alert alert-info">
                                            <h6><i class="fas fa-info-circle"></i> 密码安全建议</h6>
                                            <ul class="mb-0">
                                                <li>密码长度至少6位</li>
                                                <li>建议包含大小写字母、数字和特殊字符</li>
                                                <li>定期更换密码</li>
                                                <li>不要使用弱密码如123456</li>
                                            </ul>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                    
                    <!-- 柜格管理卡片 -->
                    <div class="col-md-12">
                        <div class="card">
                            <div class="card-header d-flex justify-content-between align-items-center">
                                <h5><i class="fas fa-boxes"></i> 柜格管理</h5>
                                <div>
                                    <button class="btn btn-primary btn-sm me-2" @click="showAddCompartmentModal = true">
                                        <i class="fas fa-plus"></i> 新增柜格
                                    </button>
                                    <button class="btn btn-warning btn-sm me-2" @click="toggleBatchMode">
                                        {{ batchMode ? '取消批量' : '批量操作' }}
                                    </button>
                                    <button v-if="batchMode && selectedCompartments.length > 0" 
                                            class="btn btn-info btn-sm me-2" 
                                            @click="showBatchStatusModal = true">
                                        批量设置状态
                                    </button>
                                    <button class="btn btn-success btn-sm me-2" @click="forceRefreshCompartments" :disabled="loading">
                                        <i class="fas fa-refresh"></i> {{ loading ? '刷新中...' : '刷新' }}
                                    </button>
                                    <button v-if="user.isAdmin" class="btn btn-secondary btn-sm" @click="debugCompartmentData">
                                        <i class="fas fa-bug"></i> 调试
                                    </button>
                                    <button v-if="user.isAdmin" class="btn btn-info btn-sm" @click="openUniquenessTest">
                                        🔒 唯一性验证测试
                                    </button>
                                </div>
                            </div>
                            <div class="card-body">
                                <!-- 筛选条件 -->
                                <div class="row mb-3">
                                    <div class="col-md-3">
                                        <select class="form-select" v-model="compartmentFilter.status" @change="filterCompartments">
                                            <option value="">所有状态</option>
                                            <option value="AVAILABLE">可用</option>
                                            <option value="OCCUPIED">占用</option>
                                            <option value="MAINTENANCE">维护</option>
                                        </select>
                                    </div>
                                    <div class="col-md-3">
                                        <select class="form-select" v-model="compartmentFilter.size" @change="filterCompartments">
                                            <option value="">所有尺寸</option>
                                            <option value="SMALL">小件</option>
                                            <option value="MEDIUM">中件</option>
                                            <option value="LARGE">大件</option>
                                        </select>
                                    </div>
                                    <div class="col-md-3">
                                        <select class="form-select" v-model="compartmentFilter.floor" @change="filterCompartments">
                                            <option value="">所有楼层</option>
                                            <option v-for="floor in availableFloors" :key="floor" :value="floor">第{{ floor }}层</option>
                                        </select>
                                    </div>
                                </div>

                                <!-- 柜格展示 -->
                                <div :key="`compartments-${refreshKey}`">
                                    <div v-for="(compartments, floor) in filteredCompartmentsByFloor" :key="`floor-${floor}-${refreshKey}`">
                                        <h6 class="border-bottom pb-2 mb-3">第{{ floor }}层</h6>
                                        <div class="compartment-grid mb-4">
                                            <div v-for="compartment in compartments" :key="`compartment-${compartment.id}-${refreshKey}`" 
                                                 :class="getCompartmentClass(compartment.compartmentStatus)"
                                                 class="compartment-item position-relative"
                                                 @click="handleCompartmentClick(compartment)">
                                                <!-- 批量选择复选框 -->
                                                <div v-if="batchMode" class="position-absolute top-0 start-0 m-1">
                                                    <input type="checkbox" 
                                                           :value="compartment.id" 
                                                           v-model="selectedCompartments"
                                                           class="form-check-input">
                                                </div>
                                                
                                                <div><strong>{{ compartment.compartmentCode }}</strong></div>
                                                <div class="small text-muted">{{ getSizeText(compartment.compartmentSize) }}</div>
                                                <div class="small">{{ getCompartmentStatusText(compartment.compartmentStatus) }}</div>
                                                
                                                <!-- 操作按钮 -->
                                                <div v-if="!batchMode" class="mt-2">
                                                    <button class="btn btn-sm btn-outline-primary me-1" 
                                                            @click.stop="editCompartment(compartment)">
                                                        编辑
                                                    </button>
                                                    <button class="btn btn-sm btn-outline-danger" 
                                                            @click.stop="deleteCompartment(compartment.id)"
                                                            :disabled="compartment.compartmentStatus === 'OCCUPIED'">
                                                        删除
                                                    </button>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                </div>

                                <!-- 空状态提示 -->
                                <div v-if="Object.keys(filteredCompartmentsByFloor).length === 0" class="text-center py-4">
                                    <p class="text-muted">暂无符合条件的柜格</p>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                
                <!-- 非管理员提示 -->
                <div v-else class="alert alert-warning" role="alert">
                    <h5>权限不足</h5>
                    <p>只有管理员才能访问柜格管理功能。</p>
                </div>
            </div>

            <!-- 消息提示 -->
            <div v-if="message" class="alert" :class="messageClass" role="alert">
                {{ message }}
            </div>
        </div>

        <!-- 管理员登录模态框 -->
        <div class="modal fade" :class="{show: showLoginModal}" :style="{display: showLoginModal ? 'block' : 'none'}" tabindex="-1">
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title">管理员登录</h5>
                        <button type="button" class="btn-close" @click="showLoginModal = false"></button>
                    </div>
                    <div class="modal-body">
                        <form @submit.prevent="adminLogin">
                            <div class="mb-3">
                                <label class="form-label">管理员密码</label>
                                <input type="password" class="form-control" v-model="loginPassword" placeholder="请输入管理员密码" required>
                            </div>
                        </form>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-secondary" @click="showLoginModal = false">取消</button>
                        <button type="button" class="btn btn-primary" @click="adminLogin" :disabled="loading">
                            {{ loading ? '登录中...' : '登录' }}
                        </button>
                    </div>
                </div>
            </div>
        </div>
        <!-- 新增/编辑柜格模态框 -->
        <div class="modal fade" :class="{show: showAddCompartmentModal}" :style="{display: showAddCompartmentModal ? 'block' : 'none'}" tabindex="-1">
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title">{{ editingCompartment ? '编辑柜格' : '新增柜格' }}</h5>
                        <button type="button" class="btn-close" @click="closeCompartmentModal"></button>
                    </div>
                    <div class="modal-body">
                        <form @submit.prevent="saveCompartment">
                            <div class="row">
                                <div class="col-md-6">
                                    <div class="mb-3">
                                        <label class="form-label">柜格编号 *</label>
                                        <input type="text" class="form-control" v-model="compartmentForm.compartmentCode" 
                                               placeholder="如：A001" required>
                                    </div>
                                </div>
                                <div class="col-md-6">
                                    <div class="mb-3">
                                        <label class="form-label">柜格尺寸 *</label>
                                        <select class="form-select" v-model="compartmentForm.compartmentSize" required>
                                            <option value="">请选择尺寸</option>
                                            <option value="SMALL">小件</option>
                                            <option value="MEDIUM">中件</option>
                                            <option value="LARGE">大件</option>
                                        </select>
                                    </div>
                                </div>
                            </div>
                            <div class="row">
                                <div class="col-md-6">
                                    <div class="mb-3">
                                        <label class="form-label">楼层 *</label>
                                        <input type="number" class="form-control" v-model="compartmentForm.floorNumber" 
                                               min="1" max="10" required>
                                    </div>
                                </div>
                                <div class="col-md-6">
                                    <div class="mb-3">
                                        <label class="form-label">位置编号 *</label>
                                        <input type="number" class="form-control" v-model="compartmentForm.positionNumber" 
                                               min="1" required>
                                    </div>
                                </div>
                            </div>
                            <div class="row">
                                <div class="col-md-6">
                                    <div class="mb-3">
                                        <label class="form-label">柜格状态</label>
                                        <select class="form-select" v-model="compartmentForm.compartmentStatus">
                                            <option value="AVAILABLE">可用</option>
                                            <option value="MAINTENANCE">维护</option>
                                        </select>
                                    </div>
                                </div>
                                <div class="col-md-6">
                                    <div class="mb-3">
                                        <label class="form-label">快递柜ID</label>
                                        <input type="text" class="form-control" v-model="compartmentForm.lockerId" 
                                               placeholder="如：LOCKER_001">
                                    </div>
                                </div>
                            </div>
                        </form>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-secondary" @click="closeCompartmentModal">取消</button>
                        <button type="button" class="btn btn-primary" @click="saveCompartment" :disabled="loading">
                            {{ loading ? '保存中...' : (editingCompartment ? '更新' : '创建') }}
                        </button>
                    </div>
                </div>
            </div>
        </div>
        <div v-if="showAddCompartmentModal" class="modal-backdrop fade show"></div>

        <!-- 批量状态更新模态框 -->
        <div class="modal fade" :class="{show: showBatchStatusModal}" :style="{display: showBatchStatusModal ? 'block' : 'none'}" tabindex="-1">
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title">批量设置柜格状态</h5>
                        <button type="button" class="btn-close" @click="showBatchStatusModal = false"></button>
                    </div>
                    <div class="modal-body">
                        <p>已选择 <strong>{{ selectedCompartments.length }}</strong> 个柜格</p>
                        <div class="mb-3">
                            <label class="form-label">目标状态</label>
                            <select class="form-select" v-model="batchStatus">
                                <option value="">请选择状态</option>
                                <option value="AVAILABLE">可用</option>
                                <option value="MAINTENANCE">维护</option>
                            </select>
                        </div>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-secondary" @click="showBatchStatusModal = false">取消</button>
                        <button type="button" class="btn btn-primary" @click="batchUpdateStatus" :disabled="!batchStatus || loading">
                            {{ loading ? '更新中...' : '批量更新' }}
                        </button>
                    </div>
                </div>
            </div>
        </div>
        <div v-if="showBatchStatusModal" class="modal-backdrop fade show"></div>
    </div>

    <!-- Bootstrap JS -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
    
    <script>
        const { createApp } = Vue;

        createApp({
            data() {
                return {
                    currentView: 'home',
                    loading: false,
                    message: '',
                    messageClass: '',
                    refreshKey: 0, // 用于强制重新渲染
                    statistics: {},
                    companies: [],
                    compartmentsByFloor: {},
                    queryResult: null,
                    showLoginModal: false,
                    loginPassword: '',
                    user: {
                        role: 'USER',
                        roleName: '普通用户',
                        isAdmin: false
                    },
                    depositForm: {
                        trackingNumber: '',
                        senderName: '',
                        senderPhone: '',
                        recipientName: '',
                        recipientPhone: '',
                        recipientAddress: '',
                        expressCompanyId: '',
                        packageSize: ''
                    },
                    pickupForm: {
                        pickupCode: '',
                        recipientPhone: ''
                    },
                    queryForm: {
                        pickupCode: '',
                        recipientPhone: '',
                        trackingNumber: '',
                        pickupCodeOnly: ''
                    },
                    // 柜格管理相关
                    showAddCompartmentModal: false,
                    showBatchStatusModal: false,
                    editingCompartment: null,
                    batchMode: false,
                    selectedCompartments: [],
                    batchStatus: '',
                    compartmentForm: {
                        compartmentCode: '',
                        compartmentSize: '',
                        compartmentStatus: 'AVAILABLE',
                        lockerId: 'LOCKER_001',
                        floorNumber: 1,
                        positionNumber: 1
                    },
                    compartmentFilter: {
                        status: '',
                        size: '',
                        floor: ''
                    },
                    filteredCompartmentsByFloor: {},
                    availableFloors: [],
                    // 密码修改表单
                    passwordForm: {
                        username: 'admin',
                        newPassword: '',
                        confirmPassword: ''
                    }
                }
            },
            async mounted() {
                await this.getCurrentUser();
                await this.loadStatistics();
                await this.loadCompanies();
                await this.loadCompartments();
            },
            watch: {
                // 监听柜格数据变化
                compartmentsByFloor: {
                    handler(newVal, oldVal) {
                        console.log('compartmentsByFloor数据发生变化:', {
                            old: oldVal,
                            new: newVal
                        });
                        // 当原始数据变化时，重新过滤
                        this.$nextTick(() => {
                            this.filterCompartments();
                        });
                    },
                    deep: true
                },
                // 监听过滤条件变化
                compartmentFilter: {
                    handler(newVal, oldVal) {
                        console.log('过滤条件发生变化:', {
                            old: oldVal,
                            new: newVal
                        });
                        this.filterCompartments();
                    },
                    deep: true
                }
            },
            methods: {
                async loadStatistics() {
                    try {
                        const response = await axios.get('/api/compartments/statistics');
                        this.statistics = response.data.data;
                    } catch (error) {
                        console.error('加载统计数据失败:', error);
                    }
                },
                async getCurrentUser() {
                    try {
                        const response = await axios.get('/api/auth/current');
                        if (response.data.code === 200) {
                            this.user = response.data.data;
                        }
                    } catch (error) {
                        console.log('获取用户信息失败:', error);
                    }
                },
                async adminLogin() {
                    if (!this.loginPassword) {
                        this.showMessage('请输入密码', 'error');
                        return;
                    }
                    
                    this.loading = true;
                    try {
                        const response = await axios.post('/api/auth/login', null, {
                            params: {
                                password: this.loginPassword
                            }
                        });
                        
                        if (response.data.code === 200) {
                            this.user = response.data.data;
                            this.showLoginModal = false;
                            this.loginPassword = '';
                            this.showMessage('登录成功！现在您可以使用管理员功能', 'success');
                        } else {
                            this.showMessage(response.data.message || '登录失败', 'error');
                        }
                    } catch (error) {
                        this.showMessage('登录失败：' + (error.response?.data?.message || error.message), 'error');
                    } finally {
                        this.loading = false;
                    }
                },
                async logout() {
                    try {
                        await axios.post('/api/auth/logout');
                        this.user = {
                            role: 'USER',
                            roleName: '普通用户',
                            isAdmin: false
                        };
                        this.showMessage('已登出管理员模式', 'success');
                    } catch (error) {
                        console.error('登出失败:', error);
                    }
                },
                async loadCompanies() {
                    try {
                        const response = await axios.get('/api/express-companies/active');
                        this.companies = response.data.data;
                    } catch (error) {
                        console.error('加载快递公司失败:', error);
                    }
                },

                async depositPackage() {
                    this.loading = true;
                    try {
                        const response = await axios.post('/api/packages/deposit', this.depositForm);
                        if (response.data.code === 200) {
                            this.showMessage('存件成功！取件码：' + response.data.data.pickupCode, 'success');
                            this.resetDepositForm();
                            await this.loadStatistics();
                            await this.loadCompartments(); // 刷新柜格数据
                        } else {
                            this.showMessage(response.data.message || '存件失败', 'error');
                        }
                    } catch (error) {
                        this.showMessage('存件失败：' + (error.response?.data?.message || error.message), 'error');
                    } finally {
                        this.loading = false;
                    }
                },
                async pickupPackage() {
                    this.loading = true;
                    try {
                        const response = await axios.post('/api/packages/pickup', this.pickupForm);
                        if (response.data.code === 200) {
                            this.showMessage('取件成功！', 'success');
                            this.resetPickupForm();
                            await this.loadStatistics();
                            await this.loadCompartments(); // 刷新柜格数据
                        } else {
                            this.showMessage(response.data.message || '取件失败', 'error');
                        }
                    } catch (error) {
                        this.showMessage('取件失败：' + (error.response?.data?.message || error.message), 'error');
                    } finally {
                        this.loading = false;
                    }
                },
                async queryByPickupCode() {
                    if (!this.queryForm.pickupCode || !this.queryForm.recipientPhone) {
                        this.showMessage('请输入取件码和收件人电话', 'error');
                        return;
                    }
                    
                    this.loading = true;
                    this.queryResult = null;
                    
                    try {
                        console.log('查询参数:', {
                            pickupCode: this.queryForm.pickupCode,
                            recipientPhone: this.queryForm.recipientPhone
                        });
                        
                        const response = await axios.get('/api/packages/query', {
                            params: {
                                pickupCode: this.queryForm.pickupCode,
                                recipientPhone: this.queryForm.recipientPhone
                            }
                        });
                        
                        console.log('查询响应:', response.data);
                        
                        if (response.data.code === 200) {
                            this.queryResult = response.data.data;
                            this.showMessage('查询成功', 'success');
                        } else {
                            this.showMessage(response.data.message || '查询失败', 'error');
                            this.queryResult = null;
                        }
                    } catch (error) {
                        console.error('查询错误:', error);
                        this.showMessage('查询失败：' + (error.response?.data?.message || error.message), 'error');
                        this.queryResult = null;
                    } finally {
                        this.loading = false;
                    }
                },
                async queryByTrackingNumber() {
                    if (!this.queryForm.trackingNumber) {
                        this.showMessage('请输入快递单号', 'error');
                        return;
                    }
                    
                    this.loading = true;
                    this.queryResult = null;
                    
                    try {
                        console.log('快递单号查询:', this.queryForm.trackingNumber);
                        
                        const response = await axios.get(`/api/packages/track/${this.queryForm.trackingNumber}`);
                        
                        console.log('快递单号查询响应:', response.data);
                        
                        if (response.data.code === 200) {
                            this.queryResult = response.data.data;
                            this.showMessage('查询成功', 'success');
                        } else {
                            this.showMessage(response.data.message || '查询失败', 'error');
                            this.queryResult = null;
                        }
                    } catch (error) {
                        console.error('快递单号查询错误:', error);
                        this.showMessage('查询失败：' + (error.response?.data?.message || error.message), 'error');
                        this.queryResult = null;
                    } finally {
                        this.loading = false;
                    }
                },
                async queryByPickupCodeOnly() {
                    if (!this.queryForm.pickupCodeOnly) {
                        this.showMessage('请输入取件码', 'error');
                        return;
                    }
                    
                    this.loading = true;
                    this.queryResult = null;
                    
                    try {
                        console.log('仅按取件码查询:', this.queryForm.pickupCodeOnly);
                        
                        const response = await axios.get('/api/packages/query-by-code', {
                            params: {
                                pickupCode: this.queryForm.pickupCodeOnly
                            }
                        });
                        
                        console.log('仅按取件码查询响应:', response.data);
                        
                        if (response.data.code === 200) {
                            this.queryResult = response.data.data;
                            this.showMessage('查询成功', 'success');
                        } else {
                            this.showMessage(response.data.message || '查询失败', 'error');
                            this.queryResult = null;
                        }
                    } catch (error) {
                        console.error('仅按取件码查询错误:', error);
                        this.showMessage('查询失败：' + (error.response?.data?.message || error.message), 'error');
                        this.queryResult = null;
                    } finally {
                        this.loading = false;
                    }
                },
                resetDepositForm() {
                    this.depositForm = {
                        trackingNumber: '',
                        senderName: '',
                        senderPhone: '',
                        recipientName: '',
                        recipientPhone: '',
                        recipientAddress: '',
                        expressCompanyId: '',
                        packageSize: ''
                    };
                },
                resetPickupForm() {
                    this.pickupForm = {
                        pickupCode: '',
                        recipientPhone: ''
                    };
                },
                showMessage(message, type) {
                    this.message = message;
                    switch(type) {
                        case 'success':
                            this.messageClass = 'alert-success';
                            break;
                        case 'info':
                            this.messageClass = 'alert-info';
                            break;
                        case 'error':
                        default:
                            this.messageClass = 'alert-danger';
                            break;
                    }
                    setTimeout(() => {
                        this.message = '';
                    }, 5000);
                },
                getStatusClass(status) {
                    switch (status) {
                        case 'DEPOSITED': return 'bg-warning text-dark';
                        case 'PICKED_UP': return 'bg-success';
                        case 'EXPIRED': return 'bg-danger';
                        default: return 'bg-secondary';
                    }
                },
                getStatusText(status) {
                    switch (status) {
                        case 'DEPOSITED': return '已存放';
                        case 'PICKED_UP': return '已取走';
                        case 'EXPIRED': return '已过期';
                        default: return status;
                    }
                },
                getCompartmentClass(status) {
                    switch (status) {
                        case 'AVAILABLE': return 'compartment-available';
                        case 'OCCUPIED': return 'compartment-occupied';
                        case 'MAINTENANCE': return 'compartment-maintenance';
                        default: return '';
                    }
                },
                getCompartmentStatusText(status) {
                    switch (status) {
                        case 'AVAILABLE': return '可用';
                        case 'OCCUPIED': return '占用';
                        case 'MAINTENANCE': return '维护';
                        default: return status;
                    }
                },
                async loadCompartments() {
                    try {
                        console.log('正在加载柜格数据...');
                        const response = await axios.get('/api/compartments/by-floor');
                        console.log('API返回数据:', response.data);
                        
                        // 先清空旧数据
                        this.compartmentsByFloor = {};
                        this.filteredCompartmentsByFloor = {};
                        
                        // 等待一个微任务，确保Vue响应式系统处理完清空操作
                        await this.$nextTick();
                        
                        // 设置新数据
                        this.compartmentsByFloor = response.data.data || {};
                        console.log('设置后的compartmentsByFloor:', this.compartmentsByFloor);
                        
                        // 等待数据设置完成
                        await this.$nextTick();
                        
                        this.updateAvailableFloors();
                        this.filterCompartments();
                        
                        // 再次等待过滤完成
                        await this.$nextTick();
                        
                        console.log('最终的filteredCompartmentsByFloor:', this.filteredCompartmentsByFloor);
                    } catch (error) {
                        console.error('加载柜格信息失败:', error);
                        this.showMessage('加载柜格数据失败：' + error.message, 'error');
                    }
                },
                // 强制刷新柜格数据的方法
                async forceRefreshCompartments() {
                    console.log('=== 开始强制刷新柜格数据 ===');
                    console.log('刷新前的数据:', JSON.stringify(this.filteredCompartmentsByFloor, null, 2));
                    
                    try {
                        // 1. 完全重置所有数据
                        this.resetCompartmentData();
                        console.log('数据已重置，refreshKey:', this.refreshKey);
                        
                        // 2. 等待DOM更新
                        await this.$nextTick();
                        console.log('DOM已更新，开始重新加载数据...');
                        
                        // 3. 重新加载数据
                        await this.loadCompartments();
                        await this.loadStatistics();
                        
                        // 4. 再次强制重新渲染
                        this.refreshKey = Date.now();
                        console.log('最终refreshKey更新为:', this.refreshKey);
                        
                        // 5. 最终等待DOM更新
                        await this.$nextTick();
                        
                        console.log('=== 强制刷新完成 ===');
                        console.log('刷新后的数据:', JSON.stringify(this.filteredCompartmentsByFloor, null, 2));
                        console.log('当前refreshKey:', this.refreshKey);
                    } catch (error) {
                        console.error('强制刷新过程中出错:', error);
                        this.showMessage('刷新数据时出错：' + error.message, 'error');
                    }
                },
                // 验证特定柜格数据的方法（用于调试）
                async verifyCompartmentData(compartmentId) {
                    try {
                        console.log('验证柜格数据，ID:', compartmentId);
                        const response = await axios.get(`/api/compartments/${compartmentId}`);
                        console.log('后端返回的柜格数据:', response.data);
                        return response.data.data;
                    } catch (error) {
                        console.error('验证柜格数据失败:', error);
                        return null;
                    }
                },
                // 调试方法：打印当前所有数据状态
                debugCompartmentData() {
                    console.log('=== 调试信息 ===');
                    console.log('当前refreshKey:', this.refreshKey);
                    console.log('compartmentsByFloor:', JSON.stringify(this.compartmentsByFloor, null, 2));
                    console.log('filteredCompartmentsByFloor:', JSON.stringify(this.filteredCompartmentsByFloor, null, 2));
                    console.log('availableFloors:', this.availableFloors);
                    console.log('compartmentFilter:', this.compartmentFilter);
                    console.log('=== 调试信息结束 ===');
                    
                    // 显示一个简单的提示
                    this.showMessage('调试信息已输出到控制台，请按F12查看', 'info');
                },
                // 完全重置所有柜格相关数据
                resetCompartmentData() {
                    console.log('重置所有柜格数据...');
                    
                    // Vue 3中直接赋值即可，不需要$set
                    this.compartmentsByFloor = {};
                    this.filteredCompartmentsByFloor = {};
                    this.availableFloors = [];
                    
                    // 重置过滤条件
                    this.compartmentFilter = {
                        status: '',
                        size: '',
                        floor: ''
                    };
                    
                    // 强制重新渲染
                    this.refreshKey = Date.now();
                },
                updateAvailableFloors() {
                    this.availableFloors = Object.keys(this.compartmentsByFloor).map(floor => parseInt(floor)).sort((a, b) => a - b);
                },
                filterCompartments() {
                    console.log('开始过滤柜格数据, 原始数据:', this.compartmentsByFloor);
                    // 创建一个全新的对象，确保Vue检测到变化
                    const newFilteredData = {};
                    
                    for (const [floor, compartments] of Object.entries(this.compartmentsByFloor)) {
                        // 深拷贝数组，确保每个对象都是新的引用
                        let filtered = compartments.map(c => ({...c}));
                        console.log(`楼层${floor}的柜格:`, compartments);
                        
                        // 按状态筛选
                        if (this.compartmentFilter.status) {
                            filtered = filtered.filter(c => c.compartmentStatus === this.compartmentFilter.status);
                        }
                        
                        // 按尺寸筛选
                        if (this.compartmentFilter.size) {
                            filtered = filtered.filter(c => c.compartmentSize === this.compartmentFilter.size);
                        }
                        
                        // 按楼层筛选
                        if (this.compartmentFilter.floor) {
                            if (parseInt(floor) !== parseInt(this.compartmentFilter.floor)) {
                                continue;
                            }
                        }
                        
                        if (filtered.length > 0) {
                            newFilteredData[floor] = filtered;
                        }
                    }
                    
                    console.log('过滤后的数据:', newFilteredData);
                    // 使用Vue.set或直接替换整个对象以触发响应式更新
                    this.filteredCompartmentsByFloor = {...newFilteredData};
                },
                handleCompartmentClick(compartment) {
                    if (!this.batchMode) {
                        // 非批量模式下显示柜格详情
                        this.showMessage(`柜格信息：${compartment.compartmentCode} - ${this.getCompartmentStatusText(compartment.compartmentStatus)}`, 'info');
                    }
                },
                toggleBatchMode() {
                    this.batchMode = !this.batchMode;
                    this.selectedCompartments = [];
                },
                editCompartment(compartment) {
                    console.log('编辑柜格，原始数据:', compartment);
                    this.editingCompartment = {...compartment}; // 深拷贝避免引用问题
                    this.compartmentForm = {
                        compartmentCode: compartment.compartmentCode,
                        compartmentSize: compartment.compartmentSize,
                        compartmentStatus: compartment.compartmentStatus,
                        lockerId: compartment.lockerId || 'LOCKER_001',
                        floorNumber: compartment.floorNumber,
                        positionNumber: compartment.positionNumber
                    };
                    console.log('编辑表单数据:', this.compartmentForm);
                    this.showAddCompartmentModal = true;
                },
                async saveCompartment() {
                    // 前端基础验证
                    if (!this.compartmentForm.compartmentCode || !this.compartmentForm.compartmentCode.trim()) {
                        this.showMessage('请输入柜格编号', 'error');
                        return;
                    }
                    
                    if (!this.compartmentForm.compartmentSize) {
                        this.showMessage('请选择柜格尺寸', 'error');
                        return;
                    }
                    
                    this.loading = true;
                    try {
                        let response;
                        const isUpdate = !!this.editingCompartment;
                        const compartmentId = isUpdate ? this.editingCompartment.id : null;
                        const originalCode = isUpdate ? this.editingCompartment.compartmentCode : null;
                        
                        console.log('=== 保存柜格操作开始 ===');
                        console.log('操作类型:', isUpdate ? '更新' : '新增');
                        console.log('柜格ID:', compartmentId);
                        console.log('原编号:', originalCode);
                        console.log('新数据:', this.compartmentForm);
                        
                        // 清理数据（去除前后空格）
                        const cleanedForm = {
                            ...this.compartmentForm,
                            compartmentCode: this.compartmentForm.compartmentCode.trim(),
                            compartmentSize: this.compartmentForm.compartmentSize.trim()
                        };
                        
                        if (isUpdate) {
                            // 更新柜格 - 使用新的带验证的API
                            response = await axios.put(`/api/compartments/${compartmentId}`, cleanedForm);
                        } else {
                            // 新增柜格 - 使用新的带验证的API
                            response = await axios.post('/api/compartments', cleanedForm);
                        }
                        
                        console.log('API响应:', response.data);
                        
                        if (response.data.success) {
                            // 显示成功消息，包含唯一性验证的提示
                            const successMsg = response.data.message || '操作成功';
                            this.showMessage(`✅ ${successMsg}`, 'success');
                            this.closeCompartmentModal();
                            
                            // 如果是更新操作且编号发生了变化，显示特别提示
                            if (isUpdate && originalCode && originalCode !== cleanedForm.compartmentCode) {
                                console.log('柜格编号发生变化，从', originalCode, '到', cleanedForm.compartmentCode);
                                this.showMessage(`🔄 柜格编号已从 "${originalCode}" 更新为 "${cleanedForm.compartmentCode}"`, 'info');
                            }
                            
                            // 强制刷新数据
                            console.log('开始强制刷新数据...');
                            await this.forceRefreshCompartments();
                            console.log('=== 保存柜格操作完成 ===');
                        } else {
                            // 显示错误消息，包含唯一性验证的错误
                            const errorMsg = response.data.message || '操作失败';
                            this.showMessage(`❌ ${errorMsg}`, 'error');
                            
                            // 如果是唯一性验证错误，给出更详细的提示
                            if (errorMsg.includes('已存在')) {
                                this.showMessage(`💡 提示：柜格编号 "${cleanedForm.compartmentCode}" 已被使用，请尝试其他编号`, 'warning');
                            }
                        }
                    } catch (error) {
                        console.error('保存柜格失败:', error);
                        const errorMessage = error.response?.data?.message || error.message;
                        this.showMessage(`❌ 操作失败：${errorMessage}`, 'error');
                        
                        // 如果是唯一性验证错误，给出特别提示
                        if (errorMessage.includes('已存在') || errorMessage.includes('重复')) {
                            this.showMessage('💡 提示：请检查柜格编号是否重复，系统不允许创建相同编号的柜格', 'warning');
                        }
                    } finally {
                        this.loading = false;
                    }
                },
                async deleteCompartment(id) {
                    if (!confirm('确定要删除这个柜格吗？')) {
                        return;
                    }
                    
                    this.loading = true;
                    try {
                        const response = await axios.delete(`/api/compartments/${id}`);
                        
                        if (response.data.code === 200) {
                            this.showMessage(response.data.data || '删除成功', 'success');
                            await this.forceRefreshCompartments();
                        } else {
                            this.showMessage(response.data.message || '删除失败', 'error');
                        }
                    } catch (error) {
                        this.showMessage('删除失败：' + (error.response?.data?.message || error.message), 'error');
                    } finally {
                        this.loading = false;
                    }
                },
                async batchUpdateStatus() {
                    if (!this.batchStatus) {
                        this.showMessage('请选择目标状态', 'error');
                        return;
                    }
                    
                    this.loading = true;
                    try {
                        const response = await axios.put('/api/compartments/batch-status', {
                            ids: this.selectedCompartments,
                            status: this.batchStatus
                        });
                        
                        if (response.data.code === 200) {
                            this.showMessage(response.data.data || '批量更新成功', 'success');
                            this.showBatchStatusModal = false;
                            this.batchStatus = '';
                            this.selectedCompartments = [];
                            this.batchMode = false;
                            await this.forceRefreshCompartments();
                        } else {
                            this.showMessage(response.data.message || '批量更新失败', 'error');
                        }
                    } catch (error) {
                        this.showMessage('批量更新失败：' + (error.response?.data?.message || error.message), 'error');
                    } finally {
                        this.loading = false;
                    }
                },
                closeCompartmentModal() {
                    this.showAddCompartmentModal = false;
                    this.editingCompartment = null;
                    this.compartmentForm = {
                        compartmentCode: '',
                        compartmentSize: '',
                        compartmentStatus: 'AVAILABLE',
                        lockerId: 'LOCKER_001',
                        floorNumber: 1,
                        positionNumber: 1
                    };
                },
                getSizeText(size) {
                    switch (size) {
                        case 'SMALL': return '小件';
                        case 'MEDIUM': return '中件';
                        case 'LARGE': return '大件';
                        default: return size;
                    }
                },
                // 密码管理相关方法
                async changePassword() {
                    // 表单验证
                    if (!this.passwordForm.username.trim()) {
                        this.showMessage('请输入用户名', 'error');
                        return;
                    }
                    
                    if (this.passwordForm.newPassword.length < 6) {
                        this.showMessage('新密码长度至少6位', 'error');
                        return;
                    }
                    
                    if (this.passwordForm.newPassword !== this.passwordForm.confirmPassword) {
                        this.showMessage('两次输入的密码不一致', 'error');
                        return;
                    }
                    
                    this.loading = true;
                    try {
                        const response = await axios.put('/api/sys-admin/change-password', null, {
                            params: {
                                username: this.passwordForm.username,
                                newPassword: this.passwordForm.newPassword
                            }
                        });
                        
                        if (response.data.code === 200) {
                            this.showMessage('密码修改成功！请使用新密码重新登录', 'success');
                            this.resetPasswordForm();
                            // 自动登出，让用户使用新密码登录
                            setTimeout(() => {
                                this.logout();
                            }, 2000);
                        } else {
                            this.showMessage(response.data.message || '密码修改失败', 'error');
                        }
                    } catch (error) {
                        this.showMessage('密码修改失败：' + (error.response?.data?.message || error.message), 'error');
                    } finally {
                        this.loading = false;
                    }
                },
                resetPasswordForm() {
                    this.passwordForm = {
                        username: 'admin',
                        newPassword: '',
                        confirmPassword: ''
                    };
                },
                formatDateTime(dateTime) {
                    if (!dateTime) return '';
                    return new Date(dateTime).toLocaleString('zh-CN');
                },
                // 打开唯一性验证测试页面
                openUniquenessTest() {
                    // 在新窗口中打开测试页面
                    window.open('test-uniqueness-vue.html', '_blank', 'width=1200,height=800,scrollbars=yes,resizable=yes');
                    this.showMessage('🔒 唯一性验证测试页面已在新窗口中打开', 'info');
                },
            }
        }).mount('#app');
    </script>
</body>
</html>